package net.ewon.avatar.agent.impl;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

import net.ewon.avatar.agent.AvatarPackageRepo;
import net.ewon.avatar.agent.RuntimeEnvironment;
import net.ewon.avatar.common.pkg.AvatarPackage;

import org.apache.commons.io.FileUtils;

public abstract class RuntimeAbstractEnvironment implements RuntimeEnvironment {

	protected String root;
	protected AvatarPackageRepo avatarPackageRepo;

	public RuntimeAbstractEnvironment(String root,
			AvatarPackageRepo avatarPackageRepo) {
		this.avatarPackageRepo = avatarPackageRepo;
		this.root = normalize(root);
	}

	@Override
	public void deploy(String environmentName,
			List<AvatarPackage> avatarPackages) throws IOException {
		String envPath = root + File.separator + environmentName;
		FileUtils.forceMkdir(new File(envPath));

		doPurge(envPath);

		for (AvatarPackage avatarPackage : avatarPackages) {
			createLink(envPath, avatarPackage);
		}

	}

	@Override
	public String getRuntimeEnvironmentRoot() {
		return root;
	}

	@Override
	public void restart(String environmentName) {

	}

	@Override
	public void startup(String environmentName) throws IOException {
		doStartup(root + File.separator + environmentName + File.separator + "bin");
	}

	@Override
	public void shutdown(String environmentName) throws IOException {
		doShutdown(root + File.separator + environmentName + File.separator + "bin");
	}
	
	protected void createLink(String envPath, AvatarPackage avatarPackage)
			throws IOException {
		Path source = Paths.get(normalize(avatarPackageRepo
				.getNormalizedBaseLocation()
				+ File.separator
				+ avatarPackage.getName()
				+ File.separator
				+ avatarPackage.getVersion()));

		Path target = Paths.get(envPath);
		LinkFiles lf = new LinkFiles(source, target);
		Files.walkFileTree(source, lf);
	}

	protected void runCommand(String dir, String command) throws IOException {
		ProcessBuilder pb = new ProcessBuilder(dir + File.separator + command);
		pb.directory(new File(dir));
		Process process = pb.start();
	}
	
	private void doPurge(String envPath) throws IOException {
		FileUtils.forceDelete(new File(envPath));
	}

	protected abstract void doShutdown(String binDir) throws IOException;

	protected abstract void doStartup(String binDir) throws IOException; 

	protected abstract String normalize(String path);

}
